package top.szhome.develop.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import top.szhome.develop.entity.Model;
import top.szhome.develop.entity.Property;
import top.szhome.develop.service.DatasourceService;
import top.szhome.develop.service.DocumentService;
import top.szhome.develop.service.ModelService;
import top.szhome.develop.service.PropertyService;

import java.io.*;
import java.util.Comparator;
import java.util.List;

/**
 * @author 唐加利
 * @date 2023/9/28
 */
@AllArgsConstructor
@Slf4j
@Service
public class DocumentServiceImpl implements DocumentService {

    private final DatasourceService datasourceService;

    private final ModelService modelService;

    private final PropertyService propertyService;

    @Override
    public void excel(Long datasourceId, OutputStream os) {
        List<Model> models = modelService.getByDatasource(datasourceId);
        models.sort(Comparator.comparing(Model::getTableName));
        try (InputStream template = buildTemplate(models);
             ExcelWriter writer = EasyExcel.write(os).withTemplate(template).build()
        ) {
            // 缓存模型ID，只为输出的Excel中有序号列
            long[] ids = new long[models.size()];
            for(int i = 0; i < models.size(); i++){
                Model model = models.get(i);
                ids[i] = model.getId();
                model.setId(i + 1L);
            }

            // 先填充目录
            WriteSheet sheet = EasyExcel.writerSheet(0).build();
            writer.fill(models, sheet);

            // 生成各个表的工作薄
            FillConfig config = new FillConfig();
            config.setForceNewRow(true);
            for(int i = 0; i < models.size(); i++){
                // 先写表信息
                Model model = models.get(i);
                sheet = EasyExcel.writerSheet(i + 1).build();
                writer.fill(model, sheet);

                // 再写字段列表
                List<Property> properties = propertyService.getProperties(ids[model.getId().intValue() - 1]);
                for(int index = 0; index < properties.size(); index++){
                    properties.get(index).setId(index + 1L);
                }
                writer.fill(new FillWrapper("property", properties), config, sheet);
            }
        } catch (Exception e) {
            log.error("生成文档失败", e);
        }
    }

    /**
     * 动态构造Excel模板
     * @param models
     * @return
     * @throws IOException
     */
    private InputStream buildTemplate(List<Model> models) throws IOException {
        File template = ResourceUtils.getFile("classpath:template/excel/database.xlsx");
        try (XSSFWorkbook book = new XSSFWorkbook(new FileInputStream(template))) {
            book.setSheetName(0, "目录");

            for(int i = 0; i < models.size(); i++){
                Model model = models.get(i);
                if(i == 0){
                    book.setSheetName(1, model.getTableName());
                } else {
                    book.cloneSheet(1, model.getTableName());
                }
            }

            ByteArrayOutputStream os = new ByteArrayOutputStream();
            book.write(os);
            return new ByteArrayInputStream(os.toByteArray());
        }
    }

    @Override
    public void word(Long datasourceId, OutputStream os) {

    }

    @Override
    public void pdf(Long datasourceId, OutputStream os) {

    }

    @Override
    public void html(Long datasourceId, OutputStream os) {

    }

}
